home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The PC-SIG Library 10
/
The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso
/
PC_SIGCD
/
22
/
4
/
DISK2247.ZIP
/
CBASE101.ZIP
/
ROLODECK.ZIP
/
ROLODECK.C
< prev
next >
Wrap
Text File
|
1990-06-21
|
23KB
|
734 lines
/* Copyright (c) 1989 Citadel */
/* All Rights Reserved */
/* #ident "@(#)rolodeck.c 1.4 - 90/06/21" */
/* ansi headers */
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
/*#include <stdlib.h>*/
/*#include <string.h>*/
/* library headers */
#include <blkio.h>
#include <cbase.h>
/* local headers */
#include "basstr.h"
#include "rolodeck.h"
#include "rolodeck.i"
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS (0)
#define EXIT_FAILURE (1)
#endif
/* constants */
#define EXPFILE ("rolodeck.txt") /* export file */
#define LMAXTRIES (100) /* maximum lock tries */
#define USAGE ("Usage: rolodeck") /* usage message */
/* rolodeck user requests */
#define RD_REQ_NEXT_CARD ('N') /* next card */
#define RD_REQ_PREV_CARD ('P') /* previous card */
#define RD_REQ_FIRST_CARD ('F') /* first card*/
#define RD_REQ_LAST_CARD ('L') /* last card */
#define RD_REQ_INS_CARD ('I') /* insert card */
#define RD_REQ_DEL_CARD ('D') /* delete card */
#define RD_REQ_SRCH_CARD ('S') /* search for card */
#define RD_REQ_TOG_SORT ('T') /* toggle sort field */
#define RD_REQ_CUR_CARD ('C') /* current card */
#define RD_REQ_ALL_CARDS ('A') /* all cards */
#define RD_REQ_IMPORT ('M') /* import cards */
#define RD_REQ_EXPORT ('X') /* export cards */
#define RD_REQ_HELP ('H') /* help */
#define RD_REQ_QUIT ('Q') /* quit */
/* function declarations */
#ifdef AC_PROTO
int fmltolfm(char *t, const char *s, size_t n);
int lfmtofml(char *t, const char *s, size_t n);
int getcard(rolodeck_t *rdp);
int putcard(const rolodeck_t *rdp);
int putmenu(int sf);
int rdlock(cbase_t *cbp, int ltype);
#else
int fmltolfm();
int lfmtofml();
int getcard();
int putcard();
int putmenu();
int rdlock();
#endif
/*man---------------------------------------------------------------------------
NAME
rolodeck - card file
SYNOPSIS
rolodeck
DESCRIPTION
rolodeck is an example program for the cbase library. In order
to allow it to be compiled without requiring a specific screen
management library, only a minimal user interface has been
implemented.
NOTES
Below are listed a few of the more important points to note when
examining the rolodeck source code.
o White space is significant in string data. For
instance, " data" != "data". Leading and
trailing white space is therefore usually
removed before storing a string in a database.
Also, embedded white space may be reduced to a
single space. The cvtss function included with
cbase will perform these string operations.
o Names are often input and displayed
first-name-first. For them to sort correctly in
a database, however, they must be stored
last-name-first. The functions fmltolfm and
lfmtofml are included with cbase to convert
between these two formats.
o bexit is used in place of exit to prevent loss
of buffered data.
The following notes concern locking.
o Single-tasking applications can simply lock
a cbase and leave it locked.
o Locks are held for shortest time possible; a
lock is never held during user input.
o A write lock should not be used when only a read
lock is required.
o When a database file is unlocked, it may be
modified by another process. A record at a
given file position may be deleted, and the
empty slot possibly reused for a new record.
Because of this, each time a file is locked,
the current record must be located by performing
a search on a unique key.
o If locking multiple cbases, deadlock must be
avoided (see The cbase Programmer's Guide).
------------------------------------------------------------------------------*/
int main(argc, argv)
int argc;
char *argv[];
{
char buf[256]; /* gp input buffer */
cbase_t * cbp = NULL; /* cbase pointer */
int found = 0; /* search flag */
rolodeck_t rd; /* rolodeck record */
int rq = 0; /* user request */
int sf = 0; /* sort field */
/* process command line options and arguments */
if (argc != 1) {
puts(USAGE);
bexit(EXIT_FAILURE);
}
/* open rolodeck cbase */
cbp = cbopen(ROLODECK, "r+", RDFLDC, rdfldv);
if (cbp == NULL) {
if (errno != ENOENT) {
fprintf(stderr, "*** Error %d opening rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
/* create rolodeck cbase */
puts("Rolodeck does not exist. Creating...");
if (cbcreate(ROLODECK, sizeof(rolodeck_t), RDFLDC, rdfldv) == -1) {
fprintf(stderr, "*** Error %d creating rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
cbp = cbopen(ROLODECK, "r+", RDFLDC, rdfldv);
if (cbp == NULL) {
fprintf(stderr, "*** Error %d opening rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
}
if (cbrecsize(cbp) != sizeof(rolodeck_t)) {
fprintf(stderr, "*** PANIC: incorrect record size.\n");
bexit(EXIT_FAILURE);
}
puts("\n--------------------------------------------------");
puts("| Rolodeck |");
puts("--------------------------------------------------\n");
/* set sort field */
sf = RD_CONTACT;
/* display menu */
putmenu(sf);
/* main loop */
memset(&rd, 0, sizeof(rd));
for (;;) {
fputs("Enter selection: ", stdout);
fgets(buf, (int)sizeof(buf), stdin);
cvtss(buf, buf, CVT_XSP | CVT_XCTL, sizeof(buf));
rq = toupper(*buf);
if (rq == RD_REQ_QUIT) { /* quit rolodeck */
break;
}
if (rq == NUL) { /* default to next card */
rq = RD_REQ_NEXT_CARD;
}
switch (rq) {
case RD_REQ_NEXT_CARD: /* next card */
if (rdlock(cbp, CB_RDLCK) == -1) {
fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
if (cbreccnt(cbp) == 0) {
puts("The rolodeck is empty.\n");
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
continue;
}
/* use unique key field to set record cursor */
found = cbkeysrch(cbp, RD_CONTACT, rd.rd_contact);
if (found == -1) {
fprintf(stderr, "*** Error %d searching for key.\n", errno);
bexit(EXIT_FAILURE);
}
/* align cursor of sort key */
if (cbkeyalign(cbp, sf) == -1) {
fprintf(stderr, "*** Error %d aligning key.\n", errno);
bexit(EXIT_FAILURE);
}
if (found == 1) {
/* advance key (and rec) cursor 1 position */
if (cbkeynext(cbp, sf) == -1) {
fprintf(stderr, "*** Error %d finding next card.\n", errno);
bexit(EXIT_FAILURE);
}
}
if (cbrcursor(cbp) == NULL) {
puts("End of deck.\n");
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
continue;
}
if (cbgetr(cbp, &rd) == -1) {
fprintf(stderr, "*** Error %d reading card.\n", errno);
bexit(EXIT_FAILURE);
}
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
putcard(&rd);
break; /* case RD_REQ_NEXT_CARD: */
case RD_REQ_PREV_CARD: /* previous card */
if (rdlock(cbp, CB_RDLCK) == -1) {
fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
if (cbreccnt(cbp) == 0) {
puts("The rolodeck is empty.\n");
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
continue;
}
/* use unique key field to set record cursor */
found = cbkeysrch(cbp, RD_CONTACT, rd.rd_contact);
if (found == -1) {
fprintf(stderr, "*** Error %d searching for key.\n", errno);
bexit(EXIT_FAILURE);
}
/* align cursor of sort key */
if (cbkeyalign(cbp, sf) == -1) {
fprintf(stderr, "*** Error %d aligning key.\n", errno);
bexit(EXIT_FAILURE);
}
/* retreat key (and rec) cursor 1 position */
if (cbkeyprev(cbp, sf) == -1) {
fprintf(stderr, "*** Error %d finding previous card.\n", errno);
bexit(EXIT_FAILURE);
}
if (cbrcursor(cbp) == NULL) {
puts("Beginning of deck.\n");
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
continue;
}
if (cbgetr(cbp, &rd) == -1) {
fprintf(stderr, "*** Error %d reading card.\n", errno);
bexit(EXIT_FAILURE);
}
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
putcard(&rd);
break; /* case RD_REQ_PREV_CARD: */
case RD_REQ_FIRST_CARD: /* first card */
if (rdlock(cbp, CB_RDLCK) == -1) {
fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
if (cbreccnt(cbp) == 0) {
puts("The rolodeck is empty.\n");
if(rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
continue;
}
if (cbkeyfirst(cbp, sf) == -1) {
fprintf(stderr, "*** Error %d finding first card.\n", errno);
bexit(EXIT_FAILURE);
}
if (cbgetr(cbp, &rd) == -1) {
fprintf(stderr, "*** Error %d reading card.\n", errno);
bexit(EXIT_FAILURE);
}
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
putcard(&rd);
break; /* case RD_REQ_FIRST_CARD: */
case RD_REQ_LAST_CARD: /* last card */
if (rdlock(cbp, CB_RDLCK) == -1) {
fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
if (cbreccnt(cbp) == 0) {
puts("The rolodeck is empty.\n");
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
continue;
}
if (cbkeylast(cbp, sf) == -1) {
fprintf(stderr, "*** Error %d finding last card.\n", errno);
bexit(EXIT_FAILURE);
}
if (cbgetr(cbp, &rd) == -1) {
fprintf(stderr, "*** Error %d reading card.\n", errno);
bexit(EXIT_FAILURE);
}
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
putcard(&rd);
break; /* case RD_REQ_LAST_CARD: */
case RD_REQ_INS_CARD: /* insert new card */
getcard(&rd);
if (strlen(rd.rd_contact) == 0) {
puts("Contact name cannot be blank. Card not inserted.\n");
memset(&rd, 0, sizeof(rd));
continue;
}
if (rdlock(cbp, CB_WRLCK) == -1) {
fprintf(stderr, "*** Error %d write locking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
if (cbinsert(cbp, &rd) == -1) {
if (errno == CBEDUP) {
printf("%s is already in the rolodeck.\n\n", rd.rd_contact);
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
continue;
}
fprintf(stderr, "*** Error %d inserting card.\n", errno);
bexit(EXIT_FAILURE);
}
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
putcard(&rd);
break; /* case RD_REQ_INS_CARD: */
case RD_REQ_DEL_CARD: /* delete current card */
if (rdlock(cbp, CB_WRLCK) == -1) {
fprintf(stderr, "*** Error %d write locking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
/* use unique key field to set record cursor */
found = cbkeysrch(cbp, RD_CONTACT, rd.rd_contact);
if (found == -1) {
fprintf(stderr, "*** Error %d searching for key.\n", errno);
bexit(EXIT_FAILURE);
}
if (found == 0) {
puts("There is no current card.\n");
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
continue;
}
/* delete record */
if (cbdelcur(cbp) == -1) {
fprintf(stderr, "*** Error %d deleting current card.\n", errno);
bexit(EXIT_FAILURE);
}
lfmtofml(buf, rd.rd_contact, sizeof(buf));
printf("%s deleted from rolodeck.\n\n", buf);
/* new current record */
switch (sf) {
default:
sf = RD_CONTACT;
case RD_CONTACT:
found = cbkeysrch(cbp, RD_CONTACT, rd.rd_contact);
if (found == -1) {
fprintf(stderr, "*** Error %d searching for key.\n", errno);
bexit(EXIT_FAILURE);
}
break;
case RD_COMPANY:
found = cbkeysrch(cbp, RD_COMPANY, rd.rd_company);
if (found == -1) {
fprintf(stderr, "*** Error %d searching for key.\n", errno);
bexit(EXIT_FAILURE);
}
break;
}
/* load rd with new current card */
if (cbrcursor(cbp) == NULL) {
memset(&rd, 0, sizeof(rd));
} else {
if (cbgetr(cbp, &rd) == -1) {
fprintf(stderr, "*** Error %d reading card.\n", errno);
bexit(EXIT_FAILURE);
}
}
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
break; /* case RD_REQ_DEL_CARD: */
case RD_REQ_SRCH_CARD: /* search for card */
if (sf == RD_CONTACT) {
fputs("Enter contact name: ", stdout);
} else {
fputs("Enter company name: ", stdout);
}
if (fgets(buf, sizeof(buf), stdin) == NULL) {
fprintf(stderr, "*** Error %d reading input.\n");
bexit(EXIT_FAILURE);
}
cvtss(buf, buf, CVT_XLEADSP | CVT_XTRAILSP | CVT_1SP | CVT_XCTL, sizeof(buf));
if (sf == RD_CONTACT) {
fmltolfm(buf, buf, sizeof(buf));
}
/* don't lock until after user input */
if (rdlock(cbp, CB_RDLCK) == -1) {
fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
if (cbreccnt(cbp) == 0) {
puts("The rolodeck is empty.\n");
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
continue;
}
found = cbkeysrch(cbp, sf, buf);
if (found == -1) {
fprintf(stderr, "*** Error %d searching for key.\n", errno);
bexit(EXIT_FAILURE);
}
if (found == 0) {
printf("%s not found.\n\n", buf);
if (cbrcursor(cbp) == NULL) {
if (cbkeylast(cbp, sf) == -1) {
fprintf(stderr, "*** Error %d finding last card.\n", errno);
bexit(EXIT_FAILURE);
}
}
}
if (cbgetr(cbp, &rd) == -1) {
fprintf(stderr, "*** Error %d reading card.\n", errno);
bexit(EXIT_FAILURE);
}
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
putcard(&rd);
break; /* case RD_REQ_SRCH_CARD: */
case RD_REQ_TOG_SORT: /* toggle sort field */
switch (sf) {
case RD_CONTACT:
sf = RD_COMPANY;
break;
case RD_COMPANY:
sf = RD_CONTACT;
break;
default:
sf = RD_CONTACT;
break;
}
putmenu(sf);
break; /* case RD_REQ_TOG_SORT: */
case RD_REQ_CUR_CARD: /* display current card */
if (strlen(rd.rd_contact) == 0) {
puts("There is no current card.\n");
continue;
}
if (rdlock(cbp, CB_RDLCK) == -1) {
fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
/* use unique key field to set record cursor */
found = cbkeysrch(cbp, RD_CONTACT, rd.rd_contact);
if (found == -1) {
fprintf(stderr, "*** Error %d searching for key.\n", errno);
bexit(EXIT_FAILURE);
}
/* check if card deleted by other process */
if (found == 0) {
puts("There is no current card.\n");
} else {
if (cbgetr(cbp, &rd) == -1) {
fprintf(stderr, "*** Error %d reading card.\n", errno);
bexit(EXIT_FAILURE);
}
putcard(&rd);
}
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
break; /* case RD_REQ_CUR_CARD: */
case RD_REQ_ALL_CARDS: /* display all cards */
if (rdlock(cbp, CB_RDLCK) == -1) {
fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
if (cbreccnt(cbp) == 0) {
puts("The rolodeck is empty.\n");
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
continue;
}
if (cbkeyfirst(cbp, sf) == -1) {
fprintf(stderr, "*** Error %d setting key cursor.\n", errno);
bexit(EXIT_FAILURE);
}
while (cbkcursor(cbp, sf) != NULL) {
if (cbgetr(cbp, &rd) == -1) {
fprintf(stderr, "*** Error %d reading card.\n", errno);
bexit(EXIT_FAILURE);
}
putcard(&rd);
if (cbkeynext(cbp, sf) == -1) {
fprintf(stderr, "*** Error %d finding next card.\n", errno);
bexit(EXIT_FAILURE);
}
}
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
break; /* case RD_REQ_ALL_CARDS: */
case RD_REQ_IMPORT: /* import cards */
if (rdlock(cbp, CB_WRLCK) == -1) {
fprintf(stderr, "*** Error %d write locking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
printf("Importing cards from %s....\n", EXPFILE);
if (cbimport(cbp, EXPFILE) == -1) {
if (errno == ENOENT) {
puts("Text file not found.\n");
} else if (errno == CBEDUP) {
puts("WARNING: Duplicate card(s) in text file not imported.\n");
} else {
fprintf(stderr, "*** Error %d importing rolodeck from %s.\n", errno, EXPFILE);
bexit(EXIT_FAILURE);
}
} else {
puts("Import complete.\n");
}
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
break; /* cbase RD_REQ_IMPORT: */
case RD_REQ_EXPORT: /* export cards */
if (rdlock(cbp, CB_RDLCK) == -1) {
fprintf(stderr, "*** Error %d read locking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
printf("Exporting cards to %s....\n", EXPFILE);
if (cbexport(cbp, EXPFILE) == -1) {
fprintf(stderr, "*** Error %d exporting rolodeck to %s.\n", errno, EXPFILE);
bexit(EXIT_FAILURE);
}
puts("Export complete.\n");
if (rdlock(cbp, CB_UNLCK) == -1) {
fprintf(stderr, "*** Error %d unlocking rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
break; /* cbase RD_REQ_EXPORT: */
case RD_REQ_HELP: /* help */
putmenu(sf);
continue;
break; /* case RD_REQ_HELP: */
default:
putchar('\a'); /* beep */
continue;
break; /* default: */
}
}
/* close cbase */
if (cbclose(cbp) == -1) {
fprintf(stderr, "*** Error %d closing rolodeck.\n", errno);
bexit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
/* rdlock: lock rolodeck */
int rdlock(cbp, ltype)
cbase_t *cbp;
int ltype;
{
int i = 0;
for (i = 0; i < LMAXTRIES; i++) {
if (cblock(cbp, ltype) == -1) {
if (errno == EAGAIN) {
continue;
}
return -1;
} else {
errno = 0;
return 0;
}
}
errno = EAGAIN;
return -1;
}
/* putmenu: display menu */
int putmenu(sf)
int sf;
{
puts("-----------------------MENU-----------------------");
puts("| N - Next card P - Previous card |");
puts("| F - First card L - Last card |");
puts("| I - Insert new card D - Delete current card |");
puts("| S - Search for card T - Toggle sort field |");
puts("| C - display Current A - display All cards |");
puts("| M - iMport cards X - eXport cards |");
puts("| H - Help (menu) Q - Quit |");
puts("--------------------------------------------------");
fputs("current sort field: ", stdout);
switch (sf) {
default:
sf = RD_CONTACT;
case RD_CONTACT:
fputs("contact", stdout);
break;
case RD_COMPANY:
fputs("company", stdout);
break;
}
puts(".\n");
return 0;
}
/* getcard: input card */
int getcard(rdp)
rolodeck_t *rdp;
{
char buf[256];
int i = 0;
memset(rdp, 0, sizeof(*rdp));
printf("Contact: ");
fgets(buf, sizeof(buf), stdin);
cvtss(buf, buf, CVT_XLEADSP | CVT_XTRAILSP | CVT_1SP | CVT_XCTL, sizeof(buf));
fmltolfm(rdp->rd_contact, buf, sizeof(rdp->rd_contact));
printf("Title: ");
fgets(buf, sizeof(buf), stdin);
cvtss(rdp->rd_title, buf, CVT_XLEADSP | CVT_XTRAILSP | CVT_1SP | CVT_XCTL, sizeof(rdp->rd_title));
printf("Company: ");
fgets(buf, sizeof(buf), stdin);
cvtss(rdp->rd_company, buf, CVT_XLEADSP | CVT_XTRAILSP | CVT_1SP | CVT_XCTL, sizeof(rdp->rd_company));
puts("Street Address (2 lines):");
for (i = 0; i < 2; i++) {
fgets(buf, sizeof(buf), stdin);
cvtss(buf, buf, CVT_XLEADSP | CVT_XTRAILSP | CVT_1SP | CVT_XCTL, sizeof(buf));
sprintf(rdp->rd_addr + 40 * i, "%-40.40s", buf);
}
printf("City: ");
fgets(buf, sizeof(buf), stdin);
cvtss(rdp->rd_city, buf, CVT_XLEADSP | CVT_XTRAILSP | CVT_1SP | CVT_XCTL, sizeof(rdp->rd_city));
printf("State: ");
fgets(buf, sizeof(buf), stdin);
cvtss(rdp->rd_state, buf, CVT_XSP | CVT_XCTL, sizeof(rdp->rd_state));
printf("Zip Code: ");
fgets(buf, sizeof(buf), stdin);
cvtss(rdp->rd_zip, buf, CVT_XSP | CVT_XCTL, sizeof(rdp->rd_zip));
printf("Phone: ");
fgets(buf, sizeof(buf), stdin);
cvtss(rdp->rd_phone, buf, CVT_XSP | CVT_XCTL, sizeof(rdp->rd_phone));
printf("Extension: ");
fgets(buf, sizeof(buf), stdin);
cvtss(rdp->rd_ext, buf, CVT_XSP | CVT_XCTL, sizeof(rdp->rd_ext));
printf("Fax: ");
fgets(buf, sizeof(buf), stdin);
cvtss(rdp->rd_fax, buf, CVT_XSP | CVT_XCTL, sizeof(rdp->rd_fax));
puts("Notes (4 lines):");
for (i = 0; i < 4; i++) {
fgets(buf, sizeof(buf), stdin);
cvtss(buf, buf, CVT_XCTL, sizeof(buf));
sprintf(rdp->rd_notes + 40 * i, "%-40.40s", buf);
}
return 0;
}
/* putcard: display card */
int putcard(rdp)
const rolodeck_t *rdp;
{
char name[sizeof(rdp->rd_contact)];
lfmtofml(name, rdp->rd_contact, sizeof(name));
puts("--------------------CARD--------------------");
printf("| %-40.40s |\n", name);
printf("| %-40.40s |\n", rdp->rd_title);
printf("| %-40.40s |\n", rdp->rd_company);
printf("| %-40.40s |\n", rdp->rd_addr);
printf("| %-40.40s |\n", rdp->rd_addr + 40);
printf("| %-25.25s, %-2.2s %-10.10s |\n", rdp->rd_city, rdp->rd_state, rdp->rd_zip);
printf("| %-12.12s x%-4.4s fax %-12.12s |\n", rdp->rd_phone, rdp->rd_ext, rdp->rd_fax);
printf("| %-40.40s |\n", rdp->rd_notes);
printf("| %-40.40s |\n", rdp->rd_notes + 40);
printf("| %-40.40s |\n", rdp->rd_notes + 80);
printf("| %-40.40s |\n", rdp->rd_notes + 120);
puts("--------------------------------------------");
return 0;
}